﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Castle.Components.Common.TemplateEngine;
using ProtoBuf;
using ProtoBuf.Meta;

namespace mst_regex
{
    [ProtoContract]
    [ProtoInclude(500, typeof(StockPositions))]
    public abstract class StockPositionsBase<T> where T : IStockPosition, IPersistable
    {
        //[ProtoMember(1)]
        protected Dictionary<string, T> _listRecords = new Dictionary<string, T>();

        protected StockPositionsBase(StockExchangeType exchange, DateTime date)
        {
            StockExchange = exchange;
            EffectiveDate = date;
        }

        [ProtoMember(400)]
        public DateTime EffectiveDate { get; set; }

        public StockExchangeType StockExchange { get; set; }

        [ProtoMember(410)]
        int StockExchangeShim
        {
            get { return (int)StockExchange; }
            set { StockExchange = (StockExchangeType)value; }
        }

        public List<string> Symbols
        {
            get { return _listRecords.Keys.ToList(); }
        }

        public virtual List<T> StockPositions
        {
            get { return _listRecords.Values.ToList(); }
        }

        public T this[string index]
        {
            get { return _listRecords[index.ToUpper()]; }
        }

        public int Count
        {
            get { return _listRecords.Count; }
        }

        protected void AddItem(T record)
        {
            _listRecords.Add(record.Symbol.ToUpper(), record);
        }

        public override string ToString()
        {
            var sb = new StringBuilder();
            foreach (var record in _listRecords)
            {
                if (sb.Length == 0)
                {
                    sb.Append("[" + record.Value + "]");
                }
                else
                {
                    sb.Append(",[" + record.Value + "]");
                }
            }
            return sb.ToString();
        }

        public string ToCsv()
        {
            var sb = new StringBuilder();
            foreach (var record in _listRecords)
            {
                sb.AppendLine(record.Value.ToCsv());
            }
            return sb.ToString();
        }

        protected string ToXml<T>() where T : IStockPosition
        {
            string xmlString = null;

            try
            {
                using (var stream = new MemoryStream())
                {
                    var settings = new XmlWriterSettings
                                       {
                                           Indent = true,
                                           Encoding = Encoding.UTF8,
                                           ConformanceLevel = ConformanceLevel.Document
                                       };

                    using (var writer = XmlWriter.Create(stream, settings))
                    {
                        var serializer = new XmlSerializer(typeof (List<T>));
                        serializer.Serialize(writer, StockPositions);
                        writer.Flush();
                    }

                    stream.Seek(0, SeekOrigin.Begin);
                    xmlString = new StreamReader(stream).ReadToEnd();
                }
            }
            catch
            {
            }

            return xmlString;
        }

        public string ProcessTemplate(ITemplateEngine engine, string templateFile)
        {
            var context = new Hashtable {{"stocks", StockPositions}};

            using (var writer = new StringWriter())
            {
                engine.Process(context, templateFile, writer);
                return writer.GetStringBuilder().ToString();
            }
        }
    }
}